/*******************************************************************************
 * Copyright (c) 2001, 2002 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui.action;

import java.lang.reflect.InvocationTargetException;

import net.sourceforge.perforce.core.PerforceCorePlugin;
import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.api.IPerforceServer;
import net.sourceforge.perforce.core.api.IResolveResult;
import net.sourceforge.perforce.core.api.ResolveTypeEnum;
import net.sourceforge.perforce.core.internal.P4TeamProvider;
import net.sourceforge.perforce.core.resources.RemoteResource;
import net.sourceforge.perforce.ui.PerforceCompareEditorInput;
import net.sourceforge.perforce.ui.PerforceResourceEditionNode;
import net.sourceforge.perforce.ui.PerforceResourceNode;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;

/**
  * @version $Revision: 202 $
  * @author  <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class CompareWithHeadAction extends PerforceAction
{
	// ------------------------------------------------------------------------------ Public Methods
	
	/** @see IActionDelegate#run(IAction) */
	public void run(IAction action)
	{
		run(new IRunnableWithProgress() 
		{
			public void run(IProgressMonitor monitor) 
				throws InvocationTargetException 
			{
				triggerCompareUI();
				
				try 
				{
					final IResource[] resources = getSelectedResources();
					if (resources.length != 1) 
					{
						return;			
					}
					
					if (!resources[0].isSynchronized(IResource.DEPTH_INFINITE))
					{
						resources[0].refreshLocal(IResource.DEPTH_INFINITE, null);
					}
						
					P4TeamProvider provider = P4TeamProvider.getProvider(resources[0]);
					IPerforceServer server = provider.getPerforceServer();
					
					RemoteResource tempAncestorResource = null;
					if (resources[0] instanceof IFile)
					{
						IResolveResult[] resolveResults = 
							server.resolve(
								resources[0].getLocation().toOSString(),
								ResolveTypeEnum.AUTOMATIC, 
								IPerforceServer.RESOLVE_SIMULATE);
						if (resolveResults.length == 1)					
						{
							int revision = resolveResults[0].getRevision().intValue() - 1;
							tempAncestorResource = 
								provider.getRemoteTree(
									resources[0], "#" + revision, new NullProgressMonitor());
						}
						else
						{
							tempAncestorResource = 
								provider.getRemoteTree(
									resources[0], "#have", new NullProgressMonitor());
						}
					}
					final RemoteResource ancestorResource =	tempAncestorResource;
					final RemoteResource remoteResource = 
						provider.getRemoteTree(resources[0], "#head", new NullProgressMonitor());
											
					getShell().getDisplay().asyncExec(new Runnable()
					{
						public void run() 
						{
							PerforceCompareEditorInput input = null;
							if (ancestorResource != null)
							{
								input = new PerforceCompareEditorInput(
									new PerforceResourceNode(resources[0]), 
									new PerforceResourceEditionNode(remoteResource), 
									new PerforceResourceEditionNode(ancestorResource));
							}
							else
							{
								input = new PerforceCompareEditorInput(
									new PerforceResourceNode(resources[0]), 
									new PerforceResourceEditionNode(remoteResource), 
									null);
							}
								
							CompareUI.openCompareEditor(
								input);
						}

					});
				} 
				catch (CoreException e)
				{
					throw new InvocationTargetException(e);
				}
				catch (TeamException e) 
				{
					throw new InvocationTargetException(e);
				}
			}
		}, PROGRESS_DIALOG, false);		
	}

	// --------------------------------------------------------------------------- Protected Methods

	/** @see TeamAction#isEnabled() */
	protected boolean isEnabled() 
		throws PerforceException
	{
		IResource[] resources = getSelectedResources();
		if (resources.length != 1)
		{
			return false;
		}
			
		RepositoryProvider tempProvider = RepositoryProvider.getProvider(resources[0].getProject());
		if (tempProvider == null || !tempProvider.getID().equals(PerforceCorePlugin.getTypeId()))
		{
			return false;
		}
				
		P4TeamProvider provider = (P4TeamProvider) tempProvider;
		if (!(provider.hasRemote(resources[0])))
		{
			return false;
		}
				
		return true;
	}
	
	// ----------------------------------------------------------------------------- Private Methods
	
	/** This method will trigger the load of the Compare Component within the display thread */
	private void triggerCompareUI()
	{
		Display display = getShell().getDisplay();
		display.syncExec(new Runnable()
		{
			/** @see java.lang.Runnable#run() */
			public void run() 
			{
				CompareUIPlugin.getDefault();
			}
		});
	}			
	
}
